/*
* Copyright (C) 2012  Sven Bendel
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see <http://www.gnu.org/licenses/>.
*/
var serverPath = '//pom4us.appspot.com/';
var myPersonId;
var alarmSound;

var forbiddenCharacters = /[^\:\.a-zA-Z!0-9_\- ]/;
function setText(element, text) {
  element.innerHTML = typeof text === 'string' ?
      text.replace(forbiddenCharacters, '') :
      '';
}

// The functions triggered by the buttons on the Hangout App

function startPomodoro() {
	console.log('Pomdoro started.');
	
	// calculate end time (current time + 25 min)
	var endTime = new Date().getTime() + 25*60*1000;
	console.log('25: endTime = ' + endTime);
   gapi.hangout.data.setValue('pomodoro', '' + 1);
	gapi.hangout.data.setValue('endTime', '' + endTime);
}

var countdown = function(until) {
	var updateCountdown = function() {
		var currentTime = new Date().getTime();
		if (currentTime >= until) {
			// stop countdown when we have reached end time
			clearInterval(interval);
			if (host()) {
				var value = gapi.hangout.data.getState()['pomCount'];
				var pomodoroState = gapi.hangout.data.getValue('pomodoro');
				
				var length;
				if (pomodoroState === '1') {
					if (!value) {
						gapi.hangout.data.submitDelta({'pomCount': '' + 1});
					} else if (pomodoroState === '1'){
						gapi.hangout.data.submitDelta({'pomCount': '' + (parseInt(value) + 1)});
					}
				
					// last state was 'in Pomodoro', next will be 'Pause'
					gapi.hangout.data.setValue('pomodoro', '' + 2);
					length = 5*60*1000;
					
					var voteCount = gapi.hangout.data.getValue('voteCount');
					if (voteCount) {
						if (parseInt(voteCount)/gapi.hangout.getEnabledParticipants().length >= 0.75) {
							length = 45*60*1000;
							gapi.hangout.data.setValue('voteCount', '' + 0);
							gapi.hangout.data.setValue('voters', '' + 1);
						}
					}
				} else {
					// last state was 'Pause', next will be 'in Pomodoro'
					gapi.hangout.data.setValue('pomodoro', '' + 1);
					length = 25*60*1000;
				}
				var endTime = new Date().getTime() + length;
				gapi.hangout.data.setValue('endTime', '' + endTime);
			}
		} else {
			// continue countdown
			var timeToDisplay = until - currentTime;
			var seconds = timeToDisplay / 1000;
			var minutes = Math.floor(seconds / 60);
			seconds = seconds % 60;
			var output = '';
			if (seconds > 10) {
				output = minutes+":"+seconds;
			} else {
				output = minutes+":0"+seconds;
			}
			// remove ms
			output = output.substring(0, output.indexOf('.'));
			setText(document.getElementById('timer'), output);
		}
	}
	
	var interval = setInterval(updateCountdown, 1000);
};

// the participant with the smallest google id is the host
var host = function() {
	var myPersonId = gapi.hangout.getParticipantById(gapi.hangout.getParticipantId()).person.id;
	
	var host = true;
	var participants = gapi.hangout.getEnabledParticipants();
	var i;
	for (i = 0; i < participants.length; i++) {
		if (myPersonId > participants[i].person.id) {
			host = false;
			break;
		}
	}
	return host;
}

function breakVote() {
	console.log('Vote cast.');
	var value = 0;
	var voteCount = gapi.hangout.data.getState()['voteCount'];
	if (voteCount) {
		value = parseInt(voteCount);
	}
	
	console.log('New count is ' + value + 1);
	gapi.hangout.data.submitDelta({'voteCount': '' + (value + 1)});
	
	var myPersonId = gapi.hangout.getParticipantById(gapi.hangout.getParticipantId()).person.id;
	
	var voters = gapi.hangout.data.getValue('voters');
	if (!voters) {
		gapi.hangout.data.setValue('voters', '' + myPersonId);
	} else {
		gapi.hangout.data.submitDelta({'voters': '' + (parseInt(voters) * myPersonId)});
	}
}

function updateStateUi(state) {
  var voteCountElement = document.getElementById('voteCount');
  var pomCountElement = document.getElementById('pomCount');
  //var pomStateElement = document.getElementById('pomState');
  var voteButton = document.getElementById('breakVotePomodoroButton');
  
  var voteCount = state['voteCount'];
  var pomCount = state['pomCount'];
  var endTime = state['endTime'];
  var pomState = state['pomodoro'];
  var voters = state['voters'];
  
  if (!voteCount) {
	setText(voteCountElement, '-');
  } else {
	setText(voteCountElement, voteCount.toString());
	if (parseInt(voteCount)/gapi.hangout.getEnabledParticipants().length >= 0.75) {
		document.getElementById('breakVotePomodoroButton').disabled = true;
	}
  }
  if (!pomCount) {
	setText(pomCountElement, '-');
  } else {
	setText(pomCountElement, pomCount.toString());
  }
  if (endTime) {
	var currentTime = new Date().getTime();
	if (endTime < currentTime) {
		// no pomodoro is currently running
		setText(document.getElementById('timer'), '0:00');
	} else {
		// pomodoro is running
		countdown(endTime);
	}
  } else {
	setText(document.getElementById('timer'), '0:00');
  }
  // TODO: change colors of #pom4us according to pomodoro state
  if (!pomState) {
    //setText(pomStateElement, 'Probably no pomodoro has yet been started');
    document.getElementById('pomStartButton').disabled = false;
    voteButton.disabled = true;
  } else {
	if (pomState === '1') {
		// pomodoro is running
		//setText(pomStateElement, 'Pomodoro is running... Get to work!');
		document.getElementById('pomStartButton').disabled = true;
		voteButton.disabled = false;
		alarmSound.play();
	} else if (pomState === '2') {
		// pause
		//setText(pomStateElement, 'Pause... Relax!');
		document.getElementById('pomStartButton').disabled = true;
		voteButton.disabled = true;
		alarmSound.play();
	}
  }
  
  if (voters) {
	if (parseInt(voters) % myPersonId === 0) {
		// we have already voted
		document.getElementById('breakVotePomodoroButton').disabled = true;
	} else {
		// we have not yet voted
		document.getElementById('breakVotePomodoroButton').disabled = false;
	}
  }
}

function updateParticipantsData(participants) {
	if (host()) {
		var i = 0;
		for (i; i < participants.length; i++) {
			var participantId = participants[i].person.id;
			var voters = gapi.hangout.data.getValue('voters');
			if (voters) {
				var votersValue = parseInt(voters);
				if (votersValue % participantId === 0) {
					// the participant had voted for a break -> remove him from voters list
					gapi.hangout.data.submitDelta({'voters': '' + votersValue/participantId});
					var voteCount = gapi.hangout.data.getValue('voteCount');
					if (voteCount) {
						gapi.hangout.data.submitDelta({'voteCount': '' + (parseInt(voteCount) - 1)});
					}				
				}
			}			
		}
	}
}

// A function to be run at app initialization time which registers our callbacks
function init() {
  console.log('Init app.');

  var apiReady = function(eventObj) {
    if (eventObj.isApiReady) {
      console.log('API is ready');
	  
	  alarmSound = gapi.hangout.av.effects.createAudioResource('http://pom4us.appspot.com/static/alarm.wav');
	  
	  myPersonId = gapi.hangout.getParticipantById(gapi.hangout.getParticipantId()).person.id;
	
      gapi.hangout.data.onStateChanged.add(function(eventObj) {
        updateStateUi(eventObj.state);
      });
	  gapi.hangout.onParticipantsDisabled.add(function(eventObj) {
		updateParticipantsData(eventObj.disabledParticipants);
	  });
	  gapi.hangout.onParticipantsRemoved.add(function(eventObj) {
		updateParticipantsData(eventObj.removedParticipants);
	  });

      updateStateUi(gapi.hangout.data.getState());

      gapi.hangout.onApiReady.remove(apiReady);
    }
  };

  // This application is pretty simple, but use this special api ready state
  // event if you would like to any more complex app setup.
  gapi.hangout.onApiReady.add(apiReady);
}

gadgets.util.registerOnLoadHandler(init);
